package com.bosch.in.rtp1.ept.manager.impl;

import java.sql.SQLException;
import java.util.List;

import com.bosch.in.rtp1.ept.constant.FXFactorConstant;
import com.bosch.in.rtp1.ept.dao.FXFactorDao;
import com.bosch.in.rtp1.ept.manager.FXFactorManager;
import com.bosch.in.rtp1.ept.model.dto.FXFactor;
import com.bosch.in.rtp1.ept.model.technical.Condition4FxFactor;
import com.bosch.in.rtp1.ept.util.DaoFactory;
import com.bosch.in.rtp1.ept.util.ehcache.EhcacheFactory;

/**
 * Concrete implementation of FXFactorManager which provides service to manipulate 
 * FXFactor data, delegate data source retrieval and transaction management to 
 * DBConnectionManager attribute.  
 * @author LIV1HC
 *
 */
public class FXFactorManagerImpl implements FXFactorManager{
	
	/**
	 * used to manage connection
	 */
	private DBConnectionManager dbManager;
	/**
	 * DAO object to get LotStatus data.
	 */
	private FXFactorDao fxFactorDao;
	
	/**
	 * Look up datasource to get connection from pre-initialized connection pool
	 * @throws Exception
	 */
	public FXFactorManagerImpl() { 
	}

	@Override
	public List<FXFactor> getFXFactors(Condition4FxFactor condition4FxFactor) throws SQLException
			{		
		try {
			return this.getFxFactors(condition4FxFactor);
		} finally {
			if (dbManager != null) {
				dbManager.close();
			}
		}
	}

	@Override
	public boolean updateFXFactors(FXFactor fxFactor) throws SQLException {
		try {
			// lazy init connection
			init();
			return fxFactorDao.updateFXFactor(fxFactor);
		} finally {
			dbManager.commit();
			dbManager.close();
		}
	}

	@Override
	public boolean insertFXFactors(FXFactor fxFactor) throws SQLException {
		try {
			// lazy init connection
			init();
			return fxFactorDao.insertFXFactor(fxFactor);
		} finally {
			dbManager.commit();
			dbManager.close();
		}
	}

	@Override
	public boolean updateFXFactors(List<FXFactor> fxFactors) throws SQLException  {
		try{
			if (fxFactors.size()>0)
			{
				// lazy init connection
				init();
				for (int i=0;i<fxFactors.size();++i)
				{
					FXFactor fxFactor = fxFactors.get(i);
					//new object
					if (fxFactor.getStatus() == FXFactorConstant.UNMANAGED)
					{
						fxFactorDao.insertFXFactor(fxFactor);
					}
					else 
					{
						fxFactorDao.updateFXFactor(fxFactor);
					}
				}
				//get condition for fx factor from cache and invalidate it
			
				Condition4FxFactor condition4FxFactor = new Condition4FxFactor();
				condition4FxFactor.setYear(fxFactors.get(0).getYear());
				condition4FxFactor.setProdArea(fxFactors.get(0).getProdArea());
				condition4FxFactor.setPriority(fxFactors.get(0).getPriority());
				condition4FxFactor.builParameterValuesList();
				EhcacheFactory.getFxFactorRecords().invalidate(condition4FxFactor.getParameterValues().toString());
				//invalidate all caches for finished recipe diagrams
				EhcacheFactory.getFshRcpFactorEhcacheWrapper().invalidate();
			}
			
		}
		finally {
			if (dbManager != null) {
				dbManager.commit();
				dbManager.close();
			}
		}
		return false;
	}
	
	/***********PRIVATE METHOD****************/
	
	/**
	 * lazy initialize connection when we really need to interact with database and in case 
	 * data can't be found in caching system.
	 * @throws SQLException
	 */
	private void init() throws SQLException {
		dbManager = new DBConnectionManager();
		fxFactorDao = DaoFactory.getInstance().getFXFactorDao(dbManager.getConnection());
	}
	
	/**
	 * Try to load the list of FXFactor from cache first. 
	 * If it is not found, try loading from database
	 * @param Condition4FxFactor
	 * @return List<FXFactor>
	 * @throws SQLException
	 */
	private List<FXFactor> getFxFactors(Condition4FxFactor condition4FxFactor) throws SQLException
	{
		// try to load location list from cache
		List<FXFactor> fxFactors = EhcacheFactory.getFxFactorRecords().get(condition4FxFactor.getParameterValues().toString());
		if (fxFactors == null)
			{
				// lazy init connection
				init();
				// load location list from database if it is not in cache 
				fxFactors = fxFactorDao.getFXFactors(condition4FxFactor);
				//put location list into cache
				if (fxFactors.size()>0)
				{
					EhcacheFactory.getFxFactorRecords().put(condition4FxFactor.getParameterValues().toString(), fxFactors);
				}
			}			
		return fxFactors;
	}

}
